import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

// Log level enum
enum LogLevel {
    DEBUG, INFO, WARN, ERROR
}

// Logger interface
interface Logger {
    void log(String message);
}

// Concrete Logger implementations
class ConsoleLogger implements Logger {
    private LogLevel level;

    public ConsoleLogger(LogLevel level) {
        this.level = level;
    }

    @Override
    public void log(String message) {
        System.out.println(message);
    }

    public LogLevel getLevel() {
        return level;
    }
}

class FileLogger implements Logger {
    private LogLevel level;
    private String fileName;

    public FileLogger(LogLevel level, String fileName) {
        this.level = level;
        this.fileName = fileName;
    }

    @Override
    public void log(String message) {
        try (BufferedWriter writer = new BufferedWriter(new FileWriter(fileName, true))) {
            writer.write(message);
            writer.newLine();
        } catch (IOException e) {
            System.err.println("Error writing to file: " + e.getMessage());
        }
    }

    public LogLevel getLevel() {
        return level;
    }
}

class DatabaseLogger implements Logger {
    private LogLevel level;

    public DatabaseLogger(LogLevel level) {
        this.level = level;
    }

    @Override
    public void log(String message) {
        System.out.println("Database Logger [" + level + "]: " + message);
    }

    public LogLevel getLevel() {
        return level;
    }
}

// Decorator abstract class
abstract class LoggerDecorator implements Logger {
    protected Logger decoratedLogger;

    public LoggerDecorator(Logger decoratedLogger) {
        this.decoratedLogger = decoratedLogger;
    }

    @Override
    public void log(String message) {
        decoratedLogger.log(message);
    }
}

// Timestamp decorator
class TimestampLogger extends LoggerDecorator {
    private LogLevel level;

    public TimestampLogger(Logger decoratedLogger, LogLevel level) {
        super(decoratedLogger);
        this.level = level;
    }

    @Override
    public void log(String message) {
        String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        decoratedLogger.log(timestamp + " " + level + ": " + message);
    }
}

// UpperCase decorator
class UpperCaseLogger extends LoggerDecorator {
    public UpperCaseLogger(Logger decoratedLogger) {
        super(decoratedLogger);
    }

    @Override
    public void log(String message) {
        decoratedLogger.log(message.toUpperCase());
    }
}

// Observer interface
interface LogLevelObserver {
    void updateLogLevel(LogLevel level);
}

// Logger Manager (Subject in Observer pattern)
class LoggerManager {
    private List<LogLevelObserver> observers = new ArrayList<>();
    private LogLevel currentLevel;

    public void addObserver(LogLevelObserver observer) {
        observers.add(observer);
    }

    public void setLogLevel(LogLevel level) {
        this.currentLevel = level;
        notifyObservers();
    }

    private void notifyObservers() {
        for (LogLevelObserver observer : observers) {
            observer.updateLogLevel(currentLevel);
        }
    }
}

// Test class
public class LoggerTest {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        LoggerManager loggerManager = new LoggerManager();

        // Get log level
        System.out.print("请输入日志级别(DEBUG/INFO/WARN/ERROR)：");
        String levelInput = scanner.nextLine().toUpperCase();
        LogLevel level;
        try {
            level = LogLevel.valueOf(levelInput);
        } catch (IllegalArgumentException e) {
            System.out.println("无效的日志级别，使用默认INFO级别");
            level = LogLevel.INFO;
        }

        // Get output methods
        System.out.print("请输入日志输出方式(console/file/database)：");
        String[] outputs = scanner.nextLine().toLowerCase().split(",");

        // Create loggers
        List<Logger> loggers = new ArrayList<>();
        for (String output : outputs) {
            Logger logger;
            switch (output.trim()) {
                case "console":
                    logger = new ConsoleLogger(level);
                    break;
                case "file":
                    logger = new FileLogger(level, "log.txt");
                    break;
                case "database":
                    logger = new DatabaseLogger(level);
                    break;
                default:
                    System.out.println("无效的输出方式: " + output);
                    continue;
            }

            // Add decorators
            logger = new TimestampLogger(logger, level);
            logger = new UpperCaseLogger(logger);
            loggers.add(logger);

            // Add as observer if it implements LogLevelObserver
            if (logger instanceof LogLevelObserver) {
                loggerManager.addObserver((LogLevelObserver) logger);
            }
        }

        // Get log message
        System.out.print("请输入日志消息：");
        String message = scanner.nextLine();

        // Log message using all selected loggers
        for (Logger logger : loggers) {
            logger.log(message);
        }

        scanner.close();
    }
}
